#include "StdAfx.h"
#include "MSProvider.h"

#include "MAPISupport.h"
#include "MsgStore.h"
#include "MSLogon.h"
#include "utils.h"

#define INITGUID
#define USES_IID_IMSProvider
// #define USES_IID_IMAPISup
// #define USES_IID_IMsgStore
// #define USES_IID_IMAPIFolder
// #define USES_IID_IMessage
// #define USES_IID_IMAPIProp
// #define USES_IID_IMAPITable
#include <initguid.h>
#include <mapiguid.h>

#define MDB_OST_LOGON_UNICODE	((ULONG) 0x00000800)
#define MDB_OST_LOGON_ANSI		((ULONG) 0x00001000)


#define Log


CMSProvider::CMSProvider(LPMSPROVIDER pObj) : m_pObj(pObj), m_cRef(1)
{
	m_pObj->AddRef();
}

CMSProvider::~CMSProvider(void)
{
	m_pObj->Release();
}


STDMETHODIMP CMSProvider::QueryInterface(REFIID riid, LPVOID * ppvObj)
{
	if (!m_pObj) return E_NOINTERFACE;
	*ppvObj = NULL;
	// If the interface requested is supported by this object, return a pointer
	// to the provider, with the reference count incremented by one.
	if (riid == IID_IMSProvider  || riid == IID_IUnknown)
	{
		*ppvObj = (LPVOID)this;
		// Increase usage count of this object
		AddRef();
		return S_OK;
	}
	// If the interface is not supported, maybe the PST does.
	return m_pObj->QueryInterface(riid, ppvObj);
} // CMSProvider::QueryInterface


STDMETHODIMP_(ULONG) CMSProvider::AddRef()
{
	if (!m_pObj) {
		return NULL;
	}
	m_cRef++;
	return m_pObj->AddRef();
} // CMSProvider::AddRef


STDMETHODIMP_(ULONG) CMSProvider::Release()
{
	if (!m_pObj) {
		return 0;
	}
	Log(true,"CMSProvider::Release() called\n");
	ULONG ulRef = m_pObj->Release();

	m_cRef--;
	if (m_cRef == 0) {
		m_pObj = NULL;
		delete this;
		return 0;
	}

	return ulRef;
} // CMSProvider::Release


STDMETHODIMP CMSProvider::Shutdown(ULONG * pulFlags)
{
	HRESULT hRes = S_OK;
	Log(true,"CMSProvider::Shutdown\n");
	hRes =m_pObj->Shutdown(pulFlags);
	Log(true,"CMSProvider::Shutdown returned: 0x%08X\n", hRes);
	return hRes ;
} // CMSProvider::Shutdown


STDMETHODIMP CMSProvider::Logon(
								LPMAPISUP lpSupObj,
								ULONG ulUIParam,
								LPTSTR lpszProfileName,
								ULONG cbEntryID,
								LPENTRYID lpEntryID,
								ULONG ulFlags,
								LPCIID lpInterface,
								ULONG * lpcbSpoolSecurity,
								LPBYTE * lppbSpoolSecurity,
								LPMAPIERROR * lppMAPIError,
								LPMSLOGON * lppMSLogon,
								LPMDB * lppMDB )
{
	Log(TRUE, "CMSProvider::Logon method called");

	HRESULT hRes = S_OK;
	LPMSLOGON lpMSLogon = NULL;
	LPMDB lpMDB = NULL;

	LPPROFSECT lpProfSect = NULL;
	CMAPISupport * lpMySup = NULL;
	hRes = GetGlobalProfileObject(lpSupObj,&lpProfSect);
	lpMySup = new CMAPISupport(lpSupObj);
	if (!lpMySup) {
		Log(true,"CMSProvider::Logon: Failed to allocate new CSupport object\n");
		hRes = E_OUTOFMEMORY;
	}
	if (SUCCEEDED(hRes)) {
		ulFlags = (ulFlags & ~MDB_OST_LOGON_ANSI) | MDB_OST_LOGON_UNICODE;

		hRes = m_pObj->Logon(
			lpMySup,
			ulUIParam,
			lpszProfileName,
			cbEntryID,
			lpEntryID,
			ulFlags,
			lpInterface,
			lpcbSpoolSecurity,
			lppbSpoolSecurity,
			lppMAPIError,
			&lpMSLogon,
			&lpMDB);
	}

	// Set up the MDB to allow synchronization
	if (SUCCEEDED(hRes))
	{
		hRes = SetOLFIInOST(lpMDB);
		Log(true,"SetOLFIInOST returned 0x%08X\n", hRes);
	}

	// Wrap the outgoing MSLogon
	if ( lpMSLogon ) {
		*lppMSLogon = new CMSLogon( lpMSLogon );
	}

	// Wrap the outgoing MDB.
	if ( lpMDB ) {
		*lppMDB = new CMsgStore (lpMDB);
	}

	if (lpProfSect) lpProfSect->Release();

	return hRes;
} // CMSProvider::Logon



STDMETHODIMP CMSProvider::SpoolerLogon (LPMAPISUP	  pSupObj,
										ULONG		  ulUIParam,
										LPTSTR		  pszProfileName,
										ULONG		  cbEntryID,
										LPENTRYID	  pEntryID,
										ULONG		  ulFlags,
										LPCIID		  pInterface,
										ULONG		  cbSpoolSecurity,
										LPBYTE		  pbSpoolSecurity,
										LPMAPIERROR * ppMAPIError,
										LPMSLOGON *   ppMSLogon,
										LPMDB * 	  ppMDB)
{
	HRESULT hRes = S_OK;

	Log(true,"CMSProvider::SpoolerLogon\n");
	LPPROFSECT lpProfSect = NULL;
	CMAPISupport * pMySup = NULL;
	hRes = GetGlobalProfileObject(pSupObj,&lpProfSect);
	pMySup = new CMAPISupport(pSupObj);
	if (!pMySup)
	{
		Log(true,"CMSProvider::SpoolerLogon: Failed to allocate new CSupport object\n");
		hRes = E_OUTOFMEMORY;
	}
	if (SUCCEEDED(hRes))
	{
		hRes = m_pObj->SpoolerLogon(
			pMySup, // pSupObj,
			ulUIParam,
			pszProfileName,
			cbEntryID,
			pEntryID,
			ulFlags,
			pInterface,
			cbSpoolSecurity,
			pbSpoolSecurity,
			ppMAPIError,
			ppMSLogon,
			ppMDB);
	}
	Log(true,"CMSProvider::SpoolerLogon returned 0x%08X\n", hRes);

	return hRes;
}



STDMETHODIMP CMSProvider::CompareStoreIDs (ULONG	 cbEntryID1,
										   LPENTRYID pEntryID1,
										   ULONG	 cbEntryID2,
										   LPENTRYID pEntryID2,
										   ULONG	 ulFlags,
										   ULONG *	 pulResult)
{
	HRESULT hRes = S_OK;

	Log(true,"CMSProvider::CompareStoreIDs\n");
	hRes = m_pObj->CompareStoreIDs(cbEntryID1, pEntryID1, cbEntryID2, pEntryID2, ulFlags, pulResult);

	Log(true,"CMSProvider::CompareStoreIDs returned 0x%08X\n", hRes);
	return hRes;
}


